﻿using pbvs.Data;
using pbvs.Models.DomainModels;
using pbvs.Models.ViewModels;
using pbvs.Calculations;
using pbvs.Models;
using pbvs.Services.Interfaces;
using pbvs.Services.ServiceExtensions;
using pbvs.Utilities;
using System;
using pbvs.Data.Repositories.Interfaces;
using pbvs.Data.Repositories.RepositoryExtensions;
using System.Linq;
using System.Collections.Generic;
using System.Web;

namespace pbvs.Services
{
	public class PbvsService : IPbvsService
	{
		private readonly PbvsContext _db;
		private readonly VariablesFull _vars;
        private readonly IValuationRepository _valuations;

		public PbvsService(PbvsContext db, VariablesFull vars, IValuationRepository valuations)
		{
			this._db = db;
			this._vars = vars;
            this._valuations = valuations;
		}

		public Valuation PerformValuation(ValuationRequestDomainModel req)
		{
			return new Valuation(req, this._vars);
		}

		public ValuationRequest LoadRequestFromViewModel(ValuationRequestDomainModel req)
		{
			ValuationRequest val = new ValuationRequest
				                       {
                                           Id = req.Id,
										   CaseId = req.CaseId,
										   PlanName = req.PlanName,
										   ParticipantFirstName = req.ParticipantFirstName,
										   ParticipantLastName = req.ParticipantLastName,
										   Gender = req.Gender,
										   Dob = req.Dob,
										   Doh = req.Doh,
										   Dot = req.Dot,
										   RetirementDate = req.RetirementDate,
										   BenefitAtRetirement = req.BenefitAtRetirement,
										   EarnedDate = req.EarnedDate,
										   AnnuityType = req.AnnuityType,
										   ValuationDate = req.ValuationDate,
										   OverrideInterest = req.OverrideInterest,
										   InterestRate = req.OverrideInterest ? req.InterestRate : Convert.ToDecimal(((IEnumerable<Default>)HttpContext.Current.Application["SiteDefaults"]).Where(d => d.Name == "First20Interest").First().Value) * 100,
                                           InterestRateThereafter = req.OverrideInterest ? req.InterestRate : Convert.ToDecimal(((IEnumerable<Default>)HttpContext.Current.Application["SiteDefaults"]).Where(d => d.Name == "InterestThereafter").First().Value) * 100,
										   SubjectToCola = req.SubjectToCola,
										   Cola = req.Cola,
										   CalculateMarriage = req.CalculateMarriage,
										   UseFractional = req.UseFractional,
										   MaritalPortion = req.MaritalPortion,
										   MarriageDate = req.MarriageDate,
										   EarningStartDate = req.EarningStartDate,
										   MarriageEarningEndDate = req.MarriageEarningEndDate,
										   Survivorship = req.Survivorship,
										   SurvivorFirstName = req.SurvivorFirstName,
										   SurvivorLastName = req.SurvivorLastName,
										   SurvivorGender = req.SurvivorGender, 
										   SurvivorDob = req.SurvivorDob,
										   SurvivorshipPercentage = req.SurvivorshipPercentage,
				                       };

			Client client = new Client
				                {
									Email = req.Client.Email,
									FirstName = req.Client.FirstName,
									LastName = req.Client.LastName,
									CompanyName = req.Client.CompanyName,
									Address = req.Client.Address,
									Address2 = req.Client.Address2,
									City = req.Client.City,
									State = req.Client.State,
									Zip = req.Client.Zip,
									Phone = req.Client.Phone
				                };

			val.Client = client;
			return val;
		}

        public bool ValidateInputs(ValuationRequest req)
        {
            return Validation.ValuationRequest(req) && Validation.Client(req.Client);
        }

		public void AddRequest(ValuationRequest req)
		{
			_db.Requests.Add(req);
		}

		public int Save()
		{
			return _db.SaveChanges();
		}

        public ValuationRequestDomainModel LoadValuation(int id)
        {
			return _valuations.Valuations.ById(id).First().ToDomainModel();
        }

        public bool ProcessValuationRequest(ValuationRequestDomainModel req)
        {
            try
            {
                bool success = false;
                ValuationRequest vr = LoadRequestFromViewModel(req);
                //if (ValidateInputs(vr))
                //{
                    success = true;
                    AddRequest(vr);
                    Save();
                    req.Id = vr.Id;
                    //PerformValuation(req);
                //}
                return success;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        public IEnumerable<ValuationRequestDomainModel> GetValuations()
        {
            return _db.Requests.AsEnumerable().Select(n => n.ToDomainModel());
        }
	}
}